home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / PhoneGroup.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  5KB  |  239 lines

  1. /*
  2. **    PhoneGroup.c
  3. **
  4. **    Phonebook group support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. VOID
  17. DeletePhoneGroupNode(PhoneGroupNode *GroupNode)
  18. {
  19.     PhoneNode *Node;
  20.  
  21.         /* Delete the group links */
  22.  
  23.     while(Node = (PhoneNode *)RemHead((struct List *)&GroupNode->GroupList))
  24.     {
  25.         Node->Entry->ThisGroup = NULL;
  26.         Node->Entry->GroupNode = NULL;
  27.  
  28.         FreeVecPooled(Node);
  29.     }
  30.  
  31.         /* Delete group node */
  32.  
  33.     FreeVecPooled(GroupNode);
  34. }
  35.  
  36. VOID
  37. FreePhoneGroupList(struct List *List)
  38. {
  39.     PhoneGroupNode *Node;
  40.  
  41.         /* Delete all the group nodes */
  42.  
  43.     while(Node = (PhoneGroupNode *)RemHead(List))
  44.         DeletePhoneGroupNode(Node);
  45. }
  46.  
  47.     /* InsertSorted(struct List *List,struct Node *Node):
  48.      *
  49.      *    Insert a node into a linked list whilst keeping the
  50.      *    list sorted in alphabetic order.
  51.      */
  52.  
  53. VOID
  54. InsertSorted(struct List *List,struct Node *Node)
  55. {
  56.     struct Node    *Other;
  57.     STRPTR         Name;
  58.  
  59.     Name = Node->ln_Name;
  60.  
  61.     for(Other = List->lh_Head ; Other->ln_Succ ; Other = Other->ln_Succ)
  62.     {
  63.         if(Stricmp(Name,Other->ln_Name) <= 0)
  64.         {
  65.             Insert(List,Node,Other->ln_Pred);
  66.  
  67.             return;
  68.         }
  69.     }
  70.  
  71.     AddTail(List,Node);
  72. }
  73.  
  74. PhoneGroupNode *
  75. CreatePhoneGroup(PhonebookHandle *PhoneHandle,STRPTR Name)
  76. {
  77.     PhoneGroupNode *Node;
  78.  
  79.         /* Check if the name already exists */
  80.  
  81.     for(Node = (PhoneGroupNode *)PhoneHandle->PhoneGroupList.mlh_Head ; Node->Node.ln_Succ ; Node = (PhoneGroupNode *)Node->Node.ln_Succ)
  82.     {
  83.         if(!Stricmp(Node->Node.ln_Name,Name))
  84.             return(Node);
  85.     }
  86.  
  87.         /* Create the new group */
  88.  
  89.     if(Node = (PhoneGroupNode *)AllocVecPooled(sizeof(PhoneGroupNode),MEMF_ANY|MEMF_CLEAR))
  90.     {
  91.             /* Set up the node name */
  92.  
  93.         strcpy(Node->Node.ln_Name = Node->LocalName,Name);
  94.  
  95.             /* Clear the list */
  96.  
  97.         NewList((struct List *)&Node->GroupList);
  98.  
  99.             /* Add the group to the global list */
  100.  
  101.         InsertSorted((struct List *)&PhoneHandle->PhoneGroupList,(struct Node *)Node);
  102.     }
  103.  
  104.     return(Node);
  105. }
  106.  
  107. VOID
  108. RemoveGroupEntry(PhoneEntry *Entry)
  109. {
  110.     if(Entry->ThisGroup)
  111.     {
  112.         PhoneNode *Node = Entry->GroupNode;
  113.  
  114.         Remove((struct Node *)Node);
  115.  
  116.         Entry->ThisGroup = NULL;
  117.     }
  118. }
  119.  
  120. VOID
  121. DeleteGroupEntry(PhoneEntry *Entry)
  122. {
  123.     if(Entry && Entry->GroupNode)
  124.     {
  125.         PhoneNode *Node = Entry->GroupNode;
  126.  
  127.         FreeVecPooled(Node);
  128.  
  129.         Entry->GroupNode = NULL;
  130.     }
  131. }
  132.  
  133. PhoneNode *
  134. AddGroupEntry(PhoneGroupNode *NewGroup,PhoneEntry *Entry)
  135. {
  136.         /* Is this entry already in a group? */
  137.  
  138.     if(Entry->ThisGroup)
  139.     {
  140.             /* Is it already in the group it should be placed in? */
  141.  
  142.         if(Entry->ThisGroup == NewGroup)
  143.             return(Entry->GroupNode);                    /* Just return the group then */
  144.         else
  145.             Remove((struct Node *)Entry->GroupNode);    /* Remove it from the old group */
  146.     }
  147.     else
  148.     {
  149.         PhoneNode *Node;
  150.  
  151.             /* Ok, so it isn't in a group yet. We'll create a new group */
  152.             /* node for it. */
  153.  
  154.         if(Node = CreatePhoneNode(Entry,TRUE))
  155.         {
  156.                 /* This points to the group the entry is in. One entry can be */
  157.                 /* only in one single group */
  158.  
  159.             Entry->GroupNode = Node;
  160.         }
  161.         else
  162.             return(NULL);
  163.     }
  164.  
  165.         /* Add the entry to the group list. Group lists are by default */
  166.         /* kept in alphabetically sorted order. */
  167.  
  168.     InsertSorted((struct List *)&NewGroup->GroupList,(struct Node *)Entry->GroupNode);
  169.  
  170.         /* Remember the group to which this entry belongs now */
  171.  
  172.     Entry->ThisGroup = NewGroup;
  173.  
  174.     return(Entry->GroupNode);
  175. }
  176.  
  177. STATIC VOID
  178. InsertGroupSorted(struct List *List,PhoneNode *Node,SORTFUNC SortFunc)
  179. {
  180.     PhoneNode    *Other;
  181.     STRPTR         Name;
  182.  
  183.     Name = Node->Node.ln_Name;
  184.  
  185.     for(Other = (PhoneNode *)List->lh_Head ; Other->Node.ln_Succ ; Other = (PhoneNode *)Other->Node.ln_Succ)
  186.     {
  187.         if((*SortFunc)(Name,Other->Node.ln_Name) <= 0)
  188.         {
  189.             Insert(List,(struct Node *)Node,Other->Node.ln_Pred);
  190.  
  191.             return;
  192.         }
  193.     }
  194.  
  195.     AddTail(List,(struct Node *)Node);
  196. }
  197.  
  198. VOID
  199. SortGroupList(struct List *List,LONG How,BOOL ReverseOrder)
  200. {
  201.     LONG Count = GetListSize(List);
  202.  
  203.     if(Count > 1)
  204.     {
  205.         PhoneEntry **Table;
  206.  
  207.         if(!(Table = (PhoneEntry **)AllocVecPooled(sizeof(PhoneEntry *) * Count,MEMF_ANY)))
  208.         {
  209.             struct List LocalList;
  210.             PhoneNode *Node;
  211.             SORTFUNC SortFunc;
  212.  
  213.             NewList(&LocalList);
  214.             MoveList(List,&LocalList);
  215.             SortFunc = GetSortFunc(How,ReverseOrder);
  216.  
  217.             while(Node = (PhoneNode *)RemHead(&LocalList))
  218.                 InsertGroupSorted(List,Node,SortFunc);
  219.         }
  220.         else
  221.         {
  222.             PhoneNode *Node;
  223.             LONG i;
  224.  
  225.             for(i = 0, Node = (PhoneNode *)List->lh_Head ; Node->Node.ln_Succ ; i++, Node = (PhoneNode *)Node->Node.ln_Succ)
  226.                 Table[i] = Node->Entry;
  227.  
  228.             qsort(Table,Count,sizeof(PhoneEntry *),GetSortFunc(How,ReverseOrder));
  229.  
  230.             NewList(List);
  231.  
  232.             for(i = 0 ; i < Count ; i++)
  233.                 AddTail(List,(struct Node *)Table[i]->GroupNode);
  234.  
  235.             FreeVecPooled(Table);
  236.         }
  237.     }
  238. }
  239.